package org.fight;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.List;

import org.fight.logic.fightbo.FightBO;
import org.fight.net.EncryptionAndDecryptionUtil;
import org.fight.net.KcpCodec2;
import org.fight.net.KcpConstant;
import org.fight.protobuf.C2SFightMsg.ReqEnterFight;
import org.fight.protobuf.C2SFightMsg.ReqOperateFight;

import com.sojoys.artifact.factory.message.IMessage;
import com.sojoys.artifact.manager.MessageManager;
import com.sojoys.artifact.third.kcp.KCP;
import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.date.TimeInterval;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

/**
 * Hello world!
 */
public class App {


	static DatagramSocket socket = null;
	static InetSocketAddress address = null;
	static KCP kcp = null;
	static ByteBuf buf = null;
	static long nextUpdateTime = 0;
	static boolean needUpdate = true;
	static int[] decryptionKeys = EncryptionAndDecryptionUtil.getDefaultCustomDecryptionKeys();
	static int[] encryptionKeys = EncryptionAndDecryptionUtil.getDefaultCustomEncryptionKeys();
	public static void main(String[] args) throws IOException, InterruptedException {
		socket = new DatagramSocket();
//		InetSocketAddress address = new InetSocketAddress("192.168.0.108", 8881);
		address = new InetSocketAddress("127.0.0.1", 8881);
//		address = new InetSocketAddress("120.92.44.172", 8888);
		buf = Unpooled.buffer();
		
		kcp = new KCP(10) {
			@Override
			protected void output(byte[] buffer, int size) {
				DatagramPacket packet = new DatagramPacket(buffer, size, address);
				try {
					socket.send(packet);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		};
		kcp.NoDelay(1,10,2,1);
		kcp.WndSize(128, 128);
		kcp.SetMtu(470);
		
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(1);
						long now = System.currentTimeMillis();
						if (!needUpdate || nextUpdateTime > now)
							continue;
						kcp.Update(now);
						nextUpdateTime = kcp.Check(now);
					} catch (InterruptedException e2) {
						e2.printStackTrace();
					}
				}
			}
		});
		t.start();
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				// 发送 100W 条数据
				for (short i = 1; i <= 2; i++) {
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					IMessage msg = MessageManager.me().create();
					if (i <= 1) {
						msg.setBody(ReqEnterFight.newBuilder().setFightId("xxxxxxxx1xxx").setPid(123).build().toByteArray());
						msg.setCommandId(FightBO.enterFight);	
					}else {
						msg.setBody(ReqOperateFight.newBuilder().setKeyCode(10).setKeyEvent(9).build().toByteArray());
						msg.setCommandId(FightBO.operateFight);
					}
					kcp.Send(KcpCodec2.encoder(msg,encryptionKeys));
					needUpdate = true;
				}
			}
		});
		t2.start();
		
		
		TimeInterval timer = DateUtil.timer();
		while (true) {
			// 收取一个MTU大小的缓冲区
			byte[] recvBuf = new byte[kcp.IKCP_MTU_DEF];
			DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length);
			socket.receive(recvPacket);
			int status = kcp.Input(Arrays.copyOf(recvPacket.getData(),recvPacket.getLength()));
			if (status!=0) {
				continue;
			}
			needUpdate = true;
			byte[] data = new byte[255 * (kcp.IKCP_MTU_DEF - kcp.IKCP_OVERHEAD)];
			int n = kcp.Recv(data);
			System.out.println("n = " + n);
			if (n < 0) {
				continue;
			}
			System.out.println(" 客户端收到数据：" + timer.interval());	
			timer.restart();		
			buf.writeBytes(data,0,n);
			List<IMessage> msgs = KcpCodec2.decoder(buf,decryptionKeys);
			for (IMessage msg : msgs) {
				switch (msg.getCommandId()) {
				case FightBO.startFight:
					break;
				case FightBO.notifyNetFrame:
					break;
				}
				
			}
			
		}
	}
}
